package com.hmys.api.config;

import com.hmys.api.model.WebLog;
import com.hmys.api.model.WebUser;
import com.hmys.api.service.WebLogService;
import com.hmys.api.service.WebUserService;
import com.hmys.api.utils.IPUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

@Aspect
@Configuration
public class HttpAspect {

    private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);

    @Autowired
    private WebUserService userService;

    @Autowired
    private WebLogService bLogService;


    /**
     * 获取注解中对方法的描述信息 用于Controller层注解
     *
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception
     */
    public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String description = "";

        for (Method method : methods) {
            if (method.isAnnotationPresent(ApiOperation.class)) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length) {
                        description = method.getAnnotation(ApiOperation.class).value();
                        break;
                    }
                }
            }
        }
        return description;
    }

    @Pointcut("execution(public * com.hmys.api.controller.*.*(..))")
    public void log() {

    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            WebUser user = userService.getCurrentUser();
            WebLog log = new WebLog();
            //domain
            String url = request.getRequestURL().toString();
            try {
                url = URLDecoder.decode(url, "UTF-8");

                log.setUrl(url);
                //logger.info("domain={}", domain);
                //method
                String method = request.getMethod().toString();
                log.setMethod(method);
                //logger.info("method={}", request.getMethod());
                //ip
                String ip = new IPUtil().getRemoteAddrIp(request);//request.getRemoteAddr().toString();
                log.setIp(ip);
                //logger.info("ip={}", ip);

                //类方法
                String class_method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
                log.setClassMethod(class_method);
                //logger.info("class_method={}", class_method);

                //方法描述
                String description = getControllerMethodDescription(joinPoint);
                //logger.info(description);
                log.setDescription(description);

                //参数
                Enumeration<String> enu = request.getParameterNames();
                List<String> parameters = new ArrayList<>();
                while (enu.hasMoreElements()) {
                    String paraName = (String) enu.nextElement();
                    parameters.add(paraName + "=" + request.getParameter(paraName));
                }

                //logger.info("parameters={}", StringUtils.join(parameters, "&"));
                if (parameters != null && parameters.size() > 0) {
                    log.setParams(StringUtils.join(parameters, "&"));
                }

                //用户
                if (user != null) {
                    log.setUserId(user.getUserId());
                    //logger.info("user={}", user.toString());
                }

                bLogService.save(log);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @After("log()")
    public void doAfter() {
        //logger.info("doAfter");
    }

    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(JoinPoint joinPoint, Object object) {
        //logger.info("response={}", object.toString());
        //logger.info("joinPoint={}", joinPoint.toString());

        //客户注册成功，短信通知顾问或者公司管理员
//        String class_method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
//        if (class_method.equals("com.meifang.controller.ClientController.register")
//                || class_method.equals("com.meifang.controller.HomePageController.register")) {
//            Result result = (Result) object;
//            //logger.info("result={}", result.toString());
//
//            if (result.getStatus() == 0) {
//                BClient client = (BClient) result.getData();
//                Long counselorId = client.getCounselorId();
//                Long companyId = client.getCompanyId();
//                String name = client.getName();
//                String phone = client.getPhone();
//                if (client != null) {
//                    //通知顾问
//                    if (counselorId != null && counselorId > 0 && !StringUtils.isEmpty(name) && !StringUtils.isEmpty(phone)) {
//                        smsService.notice(1, counselorId, name, phone);
//                    } else {
//                        //通知公司管理员
//                        if (companyId != null && !StringUtils.isEmpty(name) && !StringUtils.isEmpty(phone)) {
//                            smsService.notice(2, companyId, name, phone);
//                        }
//                    }
//                }
//            }
//        }
    }
}
